<!doctype html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <title>Font Atlas Generator</title>
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link
      href="https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100..700;1,100..700&display=swap"
      rel="stylesheet"
    />
    <style>
      body {
        font-family: sans-serif;
        padding: 20px;
      }
      canvas {
        border: 1px solid #ccc;
        margin-top: 10px;
        image-rendering: pixelated;
      }
      label {
        display: block;
        margin: 5px 0 2px;
      }
      input[type="text"],
      input[type="number"] {
        width: 100%;
      }
      #controls {
        max-width: 300px;
      }
    </style>
  </head>
  <body>
    <h1>Bitmap Font Generator</h1>
    <div id="controls">
      <label
        >Font: <input type="text" id="fontFamily" value="Roboto Mono"
      /></label>
      <label
        >Font Size (px): <input type="number" id="fontSize" value="32"
      /></label>
      <label
        >Characters per Row: <input type="number" id="cols" value="16"
      /></label>
      <label
        >Characters:
        <input
          type="text"
          id="chars"
          value="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#b"
      /></label>
      <button id="saveBtn">Download PNG</button>
    </div>

    <canvas id="preview" width="512" height="256"></canvas>

    <script>
      const canvas = document.getElementById("preview")
      const ctx = canvas.getContext("2d")
      const fontFamilyInput = document.getElementById("fontFamily")
      const fontSizeInput = document.getElementById("fontSize")
      const colsInput = document.getElementById("cols")
      const charsInput = document.getElementById("chars")

      async function drawFontTexture() {
        const fontFamily = fontFamilyInput.value
        const fontSize = parseInt(fontSizeInput.value, 10)

        await document.fonts.load(`${fontSize}px "${fontFamily}"`)

        const cols = parseInt(colsInput.value, 10)
        // MIDIノート番号0〜127の音名配列を生成
        const noteNames = []
        const baseNames = [
          "C",
          "C#",
          "D",
          "D#",
          "E",
          "F",
          "F#",
          "G",
          "G#",
          "A",
          "A#",
          "B",
        ]
        for (let i = 0; i < 128; i++) {
          const octave = Math.floor(i / 12) - 1
          const name = baseNames[i % 12] + octave
          noteNames.push(name)
        }
        const chars = noteNames

        const rows = Math.ceil(chars.length / cols)
        const cellWidth = fontSize * 3
        const cellHeight = fontSize

        canvas.width = cols * cellWidth
        canvas.height = rows * cellHeight

        ctx.clearRect(0, 0, canvas.width, canvas.height)

        ctx.font = `300 ${fontSize}px "${fontFamily}"`
        ctx.fillStyle = "black"
        ctx.textAlign = "left"
        ctx.textBaseline = "middle"

        for (let i = 0; i < chars.length; i++) {
          const char = chars[i]
          const col = i % cols
          const row = Math.floor(i / cols)
          const x = col * cellWidth + 4 // 左端+余白
          const y = row * cellHeight + cellHeight / 2
          ctx.fillText(char, x, y)
        }
      }

      function saveImage() {
        const link = document.createElement("a")
        link.download = "font-atlas.png"
        link.href = canvas.toDataURL()
        link.click()
      }

      document.getElementById("saveBtn").addEventListener("click", saveImage)

      // 設定変更時に再描画
      ;[fontFamilyInput, fontSizeInput, colsInput, charsInput].forEach(
        (input) => input.addEventListener("input", drawFontTexture),
      )

      // 初期描画
      drawFontTexture()
    </script>
  </body>
</html>
